import React, { useState, useEffect } from "react";
import { View, StyleSheet, Dimensions, Text, Image, TouchableOpacity, Clipboard, FlatList } from "react-native";
import { Divider, Input, Icon, Button } from "@rneui/themed";
import LinearGradinet from 'react-native-linear-gradient';
import { useSelector, useDispatch } from "react-redux";
import web3Utils from 'web3-utils'
import api from "@/request/api";
import Toast from 'react-native-simple-toast'
import RightImg from '@/assets/safe/right.png'
import IconNavBar from '@/components/IconNavBar'
import ModalMenu from "@/components/ModalMenu";
import ScanModal from '@/components/ScanModal'
import Loading from "@/components/LoadingModal";
import CommonContext from '@/utils/createContext'
import { sectokenCreateProps } from '@/config/navigatorProps'
import { CoinArray, PayWithArray, LabelArray } from '@/config/config'
import { getValue, setObjectValue } from '@/utils/deviceStorage'
import { AESdecrypt, guid } from '@/utils/util'
import { createWallet, getTransactionReceipt, getFeeData } from '@/utils/safe-transfer'
import { getETHBalance } from "@/utils/transfer";

const { width, scale } = Dimensions.get('window')
const ratio = width * scale / 1080

const SectokenCreate = (props) => {

    const dispatch = useDispatch();
    const selectedPayWith = useSelector((state) => state.sectokenSafeReducer.selectedPayWith || {});
    const feeData = useSelector((state) => state.sectokenSafeReducer.feeData || {});
    const [coinType, setCoinType] = useState('')
    const [loadingVisible, setLoadingVisible] = useState(false)
    const [safeName, setSafeName] = useState('')
    const [ownerList, setOwnerList] = useState([])
    const [ownerNumber, setOwnerNumber] = useState(1)
    const [menuVisible, setMenuVisible] = useState(false)
    const [cameraVisible, setCameraVisible] = useState(false)

    useEffect(() => {
        setLoadingVisible(true)
        setTimeout(() => {
            getPageData().then(() => setLoadingVisible(false))
                .catch(() => setLoadingVisible(false))
        }, 100);
    }, [])

    const getPageData = async () => {
        let obj = getValue('selectedWallet')
        let str = getValue('coinType')
        setCoinType(str)
        if (obj && obj.address) {
            setOwnerList([obj.address])
            let res = await getFeeData(obj.address, [obj.address], 1)
            dispatch({ type: "setFeeData", value: res || [] });
        }

        let list = getValue('walletList')
        if (list && list.length > 0) {
            for (let i = 0; i < list.length; i++) {
                let profileImg = Object.keys(PayWithArray)[Math.floor(Math.random() * 3)]
                let balance = await getETHBalance(list[i].address)
                list[i].value = balance
                list[i].profileImg = profileImg
            }
            dispatch({ type: "setSelectedPayWith", value: list[0] || {} });
            dispatch({ type: "setPayWithList", value: list || [] });
        }
    }

    const handlePressPlus = () => {
        setMenuVisible(true)
    }

    const handlePressAdd = () => {
        if (ownerNumber < ownerList.length) {
            setOwnerNumber(ownerNumber + 1)
        }
    }

    const handlePressMinus = () => {
        if (ownerNumber > 1) {
            setOwnerNumber(ownerNumber - 1)
        }
    }

    const handlePressCreate = () => {
        if (safeName && ownerList && ownerList.length > 0
            && selectedPayWith && feeData) {
            setLoadingVisible(true)
            setTimeout(async () => {
                let profileImg = Object.keys(PayWithArray)[Math.floor(Math.random() * 3)]
                let label = LabelArray[Math.floor(Math.random() * 7)]
                let ownerArr = ownerList.map((item, index) => {
                    let obj = {
                        profileImg,
                        label: `${label}${index + 1}`,
                        address: item
                    }
                    return obj
                })
                let pwd = getValue('lockPwd')
                let encryptStr = getValue('mnemonicStr')
                let decryptStr = AESdecrypt(pwd.substring(0, 16), pwd.substring(16), encryptStr)
                let obj = JSON.parse(JSON.stringify(feeData))
                let gaslimit = parseInt(parseInt(obj.gasConsume?.hex) * 1.3)
                obj.gasConsume = {
                    "type": "BigNumber",
                    "hex": "0x" + gaslimit.toString(16)
                }
                let txHash = await createWallet(ownerList, ownerNumber, decryptStr, obj)
                var t = setInterval(async () => {
                    const tx = await getTransactionReceipt(txHash)
                    if (tx) {
                        clearInterval(t)
                        let contractAddress = tx.logs[0].address;
                        let safeWallet = {
                            id: guid(),
                            address: contractAddress,
                            label: safeName,
                            ownerList: ownerArr,
                            payWith: selectedPayWith,
                            feeData,
                            ownerNumber,
                            profileImg: selectedPayWith.profileImg
                        }
                        let result = getValue('safeWalletList')
                        let arr = []
                        if (result && result.length > 0) {
                            result.push(safeWallet)
                            arr = result
                        } else {
                            arr.push(safeWallet)
                        }
                        setObjectValue('safeWalletList', [...arr])
                        dispatch({ type: "setSelectedSafeWallet", value: safeWallet || {} });
                        setLoadingVisible(false)
                        props.navigation.navigate({
                            name: 'safe-main',
                            params: {
                                source: 'create-safe',
                                load: true
                            }
                        })
                    }
                }, 3000)
            }, 100);
        }
    }

    const handlePressLeft = () => {
        props.navigation.goBack()
    }

    const handlePressPayWith = () => {
        props.navigation.navigate('safe-create-pay-with')
    }

    const handlePressNetFee = () => {
        props.navigation.navigate('safe-create-net-fee')
    }

    const checkAddress = (content) => {
        //1.检查地址的有效性，调用web3.utils.toChecksumAddress
        let result = web3Utils.checkAddressChecksum(content)
        if (result) {
            setLoadingVisible(true)
            //2.调用接口查询地址的类型，合约地址或普通地址
            api.check_address(content).then(res => {
                if (res.result === '0x') {
                    ownerList.push(content)
                    setOwnerList([...ownerList])
                } else {
                    Toast.showWithGravity(
                        'This address is invalid!',
                        Toast.SHORT,
                        Toast.CENTER)
                }
                setLoadingVisible(false)
            }).catch(() => {
                Toast.showWithGravity(
                    'This address is invalid!',
                    Toast.SHORT,
                    Toast.CENTER)
                setLoadingVisible(false)
            })
        } else {
            Toast.showWithGravity(
                'This address is invalid!',
                Toast.SHORT,
                Toast.CENTER)
        }
    }

    const handlePressPaste = async () => {
        let content = await Clipboard.getString();
        if (content && content.length > 0) {
            if (ownerList.includes(content)) {
                Toast.showWithGravity(
                    'This address already exists!',
                    Toast.SHORT,
                    Toast.CENTER)
            } else {
                //校验地址
                checkAddress(content)
            }
        }
        setMenuVisible(false)
    }

    const handlePressScan = () => {
        setMenuVisible(false)
        setCameraVisible(true)
    }

    const handleReadCode = (result) => {
        const { data } = result;
        if (data && data.length > 0) {
            if (ownerList.includes(data)) {
                Toast.showWithGravity(
                    'This address is invalid!',
                    Toast.SHORT,
                    Toast.CENTER)
            } else {
                checkAddress(data)
            }
        }
        setCameraVisible(false)
    }

    const renderOwnerItem = ({ item }) => (
        <Text ellipsizeMode='middle' numberOfLines={1}
            style={{ ...styles.title3, width: 280 * ratio, marginLeft: 15 * ratio, color: '#767B7D' }}>
            {item}
        </Text>
    );

    return (
        <View style={{ ...styles.container, backgroundColor: menuVisible ? '#000000' : '#F7F7F7', opacity: menuVisible ? 0.2 : 1 }}>
            {!cameraVisible &&
                <View>
                    <IconNavBar {...props} {...sectokenCreateProps} handlePressLeft={handlePressLeft} />
                    <View style={{ height: 44 * ratio, backgroundColor: '#FFFFFF', flexDirection: 'row', alignItems: 'center', marginTop: 15 * ratio }}>
                        <Image source={CoinArray[coinType]} style={{ ...styles.img1, marginLeft: 15 * ratio }} />
                        <Text style={{ ...styles.title1, marginLeft: 13 * ratio }}>{coinType}</Text>
                    </View>
                    <Text style={{ ...styles.title2, color: '#A0A0A0', marginLeft: 15 * ratio, marginTop: 6 * ratio }}>
                        Safe will only exist on the selected network.
                    </Text>
                    <Text style={{ ...styles.title1, marginLeft: 15 * ratio, marginTop: 24 * ratio }}>
                        Safe Name
                    </Text>
                    <Input
                        containerStyle={{ ...styles.text_input, paddingLeft: 15 * ratio, marginTop: 15 * ratio }}
                        onChangeText={text => setSafeName(text)}
                        value={safeName}
                        placeholder='Enter name'
                        placeholderTextColor='#767B7D'
                        inputContainerStyle={{ borderBottomWidth: 0 }}
                        inputStyle={{ fontSize: 14 }}
                    />
                    <Text style={{ ...styles.title1, marginLeft: 15 * ratio, marginTop: 23 * ratio }}>
                        Add Owner
                    </Text>
                    <View style={{ minHeight: 44 * ratio, backgroundColor: '#FFFFFF', marginTop: 15 * ratio, flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>
                        <FlatList
                            data={ownerList}
                            renderItem={renderOwnerItem}
                            keyExtractor={(item, index) => index}
                        />
                        <Icon style={{ marginRight: 15 * ratio }} type='antdesign' name='pluscircleo' color='#535353' size={20} onPress={handlePressPlus} />
                    </View>
                    <Text style={{ ...styles.title2, color: '#A0A0A0', marginLeft: 15 * ratio, marginTop: 6 * ratio }}>
                        add an owner by pasting or scanning an eth address
                    </Text>
                    <View style={{ height: 44 * ratio, backgroundColor: '#FFFFFF', flexDirection: 'row', alignItems: 'center', marginTop: 23 * ratio }}>
                        <View style={{ flex: 5 }}>
                            <Text style={{ ...styles.title1, marginLeft: 15 * ratio }}>
                                {ownerNumber} out of {ownerList.length || 1}
                            </Text>
                        </View>
                        <View style={{ flex: 5, alignItems: 'flex-end' }}>
                            <View style={{
                                flexDirection: 'row', marginRight: 15 * ratio, justifyContent: 'center',
                                width: 70 * ratio, backgroundColor: '#EDEDED', borderRadius: 2
                            }}>
                                <Button type="clear" onPress={handlePressMinus}>
                                    <Icon type='antdesign' name="minus" color="#000000" size={12} />
                                </Button>
                                <Divider />
                                <Button type="clear" onPress={handlePressAdd}>
                                    <Icon type='antdesign' name="plus" color="#000000" size={12} />
                                </Button>
                            </View>
                        </View>
                    </View>
                    <Text style={{ ...styles.title2, width: 285 * ratio, color: '#A0A0A0', marginLeft: 15 * ratio }}>
                        how many owner confirmations are required for a
                        transaction to be executed?learn about safe setup
                    </Text>
                    <View style={{ height: 104 * ratio, backgroundColor: '#FFFFFF', marginTop: 25 * ratio }}>
                        <TouchableOpacity onPress={handlePressPayWith}>
                            <View style={{ height: 51 * ratio, flexDirection: 'row', alignItems: 'center' }}>
                                <View style={{ flex: 5 }}>
                                    <Text style={{ ...styles.title1, marginLeft: 15 * ratio }}>
                                        Pay with
                                    </Text>
                                </View>
                                <View style={{ flex: 5, flexDirection: 'row', justifyContent: 'flex-end', alignItems: 'center' }}>
                                    <Image source={PayWithArray[selectedPayWith.profileImg]} style={{ ...styles.img3, marginRight: 15 * ratio }} />
                                    <View style={{ marginRight: 17 * ratio }}>
                                        <Text style={styles.title3}>{selectedPayWith.wallet_name}</Text>
                                        <Text style={styles.title4}>{selectedPayWith.value?.substring(0, 9)}{coinType}</Text>
                                    </View>
                                    <Image source={RightImg} style={{ ...styles.img4, marginRight: 15 * ratio }} />
                                </View>
                            </View>
                        </TouchableOpacity>
                        <Divider color="#EAEAEA" />
                        <TouchableOpacity onPress={handlePressNetFee}>
                            <View style={{ height: 51 * ratio, flexDirection: 'row', alignItems: 'center' }}>
                                <View style={{ flex: 5 }}>
                                    <Text style={{ ...styles.title1, marginLeft: 15 * ratio }}>
                                        Network fee
                                    </Text>
                                </View>
                                <View style={{ flex: 5, flexDirection: 'row', justifyContent: 'flex-end', alignItems: 'center' }}>
                                    <Text style={{ ...styles.title1, marginRight: 15 * ratio }}>
                                        {feeData.totalFee?.substring(0, 9)} {coinType}
                                    </Text>
                                    <Image source={RightImg} style={{ ...styles.img4, marginRight: 15 * ratio }} />
                                </View>
                            </View>
                        </TouchableOpacity>
                    </View>
                    <View style={{ justifyContent: 'center', alignItems: 'center', marginTop: 16 * ratio }}>
                        <TouchableOpacity onPress={handlePressCreate}>
                            <LinearGradinet colors={['#0EBBF8', '#0069F6']} start={{ x: 0, y: 0 }} end={{ x: 1, y: 0 }} style={styles.button}>
                                <Text style={{ ...styles.title1, color: '#FFFFFF', textAlign: 'center' }}>Create new Safe</Text>
                            </LinearGradinet>
                        </TouchableOpacity>
                    </View>
                </View>
            }
            <CommonContext.Provider value={{ modalVisible: menuVisible, setModalVisible: setMenuVisible, handlePressPaste, handlePressScan }}>
                <ModalMenu />
            </CommonContext.Provider>
            <CommonContext.Provider value={{ modalVisible: cameraVisible, setModalVisible: setCameraVisible, handleReadCode }}>
                <ScanModal />
            </CommonContext.Provider>
            {loadingVisible && <Loading visible={loadingVisible} />}
        </View>
    )
}

const styles = StyleSheet.create({
    container: {
        flex: 1
    },
    img1: {
        width: 30 * ratio,
        height: 30 * ratio
    },
    img3: {
        width: 22 * ratio,
        height: 22 * ratio
    },
    img4: {
        width: 5 * ratio,
        height: 9 * ratio
    },
    title1: {
        fontSize: 16,
        fontFamily: 'SourceHanSansCN-Medium, SourceHanSansCN',
        fontWeight: '500',
        lineHeight: 24,
        color: '#2C2C2C'
    },
    title3: {
        fontSize: 14,
        fontFamily: 'SourceHanSansCN-Medium, SourceHanSansCN',
        fontWeight: '500',
        lineHeight: 21,
        color: '#2C2C2C'
    },
    title2: {
        fontSize: 12,
        fontFamily: 'SourceHanSansCN-Regular, SourceHanSansCN',
        fontWeight: '400',
        lineHeight: 18,
        color: '#A0A0A0'
    },
    title4: {
        fontSize: 11,
        fontFamily: 'SourceHanSansCN-Medium, SourceHanSansCN',
        fontWeight: '500',
        lineHeight: 17
    },
    text_input: {
        width: width,
        height: 44 * ratio,
        backgroundColor: '#FFFFFF'
    },
    button: {
        width: 332 * ratio,
        height: 50,
        borderRadius: 28,
        justifyContent: 'center'
    }
})
export default SectokenCreate